package com.jmuok.web.fff.web;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.vaadin.navigator.Navigator;

import com.jmuok.web.fff.web.LoginWindow.LoginEvent;
import com.jmuok.web.fff.web.vaadin.BaseApplication;
import com.vaadin.Application;
import com.vaadin.service.ApplicationContext.TransactionListener;
import com.vaadin.ui.Component.Event;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.Runo;

@Component("com.jmuok.web.fff.web.IndexApplication")
@Scope("prototype")
public class IndexApplication extends BaseApplication implements
		TransactionListener {

	private static final long serialVersionUID = 7140505132100646109L;
	private static final Log logger = LogFactory.getLog(IndexApplication.class);
	private final static String CHECK_URL = "fff_security_check";
	private Navigator navigator;

	@Resource
	private AuthenticationManager authenticationManager;

	@Override
	public void init() {
		setTheme(Runo.themeName());

		Window loginWindow = new LoginWindow(this, authenticationManager);
		setMainWindow(loginWindow);
		loginWindow.addListener(new com.vaadin.ui.Component.Listener() {

			@Override
			public void componentEvent(Event event) {
				if (event instanceof LoginWindow.LoginEvent) {
					LoginEvent le = (LoginEvent) event;
					setUser(le.getAuthentication());
					SecurityContextHolder.getContext().setAuthentication(
							le.getAuthentication());
					setMainWindow(new Window("login success"));
					if (logger.isDebugEnabled()) {
						logger.debug("login success");
					}
				}
			}
		});

		// add navigator
		getMainWindow().addComponent(initNavigator());
	}

	public Navigator initNavigator() {
		navigator = new Navigator();
		navigator.setWidth("100.0%");
		navigator.setHeight("100.0%");
		navigator.setImmediate(false);
		// navigator.addView("UserReg", UserRegView.class);
		navigator.addView(CHECK_URL, LoginCheckView.class);
		return navigator;
	}

	@Override
	public void transactionEnd(Application application, Object transactionData) {
		if (logger.isDebugEnabled()) {
			logger.debug("Transaction ended, removing authentication data from security context");
		}
		/*
		 * The purpose of this
		 */
		SecurityContextHolder.getContext().setAuthentication(null);
	}

	@Override
	public void transactionStart(Application application, Object transactionData) {
		if (logger.isDebugEnabled()) {
			logger.debug("Transaction started, setting authentication data of security context to ["
					+ application.getUser() + "]");
		}
		/*
		 * The security context holder uses the thread local pattern to store
		 * its authentication credentials. As requests may be handled by
		 * different threads, we have to update the security context holder in
		 * the beginning of each transaction.
		 */
		SecurityContextHolder.getContext().setAuthentication(
				(Authentication) application.getUser());
	}
	// private void doLogin(String username, String password) {
	// UsernamePasswordAuthenticationToken authRequest = new
	// UsernamePasswordAuthenticationToken(
	// username, password);
	//
	// authRequest.setDetails(new WebAuthenticationDetails(request))
	//
	// Authentication authResult;
	// try {
	// authResult = getAuthenticationManager().authenticate(authRequest);
	// } catch (AuthenticationException failed) {
	// unsuccessfulAuthentication(request, response, failed);
	// return;
	// }
	// successfulAuthentication(request, response, chain, authResult);
	// }
}
